package com.mall.common.service;

import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaQuery;

import com.mall.common.bean.Order;
import com.mall.common.bean.Pager;
import com.mall.common.bean.SearchFilter;
import com.mall.common.hibernate.Finder;
import com.mall.common.hibernate.Updater;
import com.mall.common.hibernate.Updater.UpdateMode;

/**
 * Service接口 - Service接口基类
 */
public interface BaseService<T, PK extends Number> {

	public EntityManager getEntityManager();
	
	/**
	 * 根据ID获取实体对象.
	 * 
	 * @param id
	 *            记录ID
	 * @return 实体对象
	 */
	public T find(PK id);
	
	/**
	 * 根据ID数组获取实体对象集合.
	 * 
	 * @param ids
	 *            ID对象数组
	 * 
	 * @return 实体对象集合
	 */
	public List<T> get(PK[] ids);
	
	public List<T> get(String[] ids);
	
	/**
	 * 根据属性名和属性值获取实体对象.
	 * 
	 * @param propertyName
	 *            属性名称
	 * @param value
	 *            属性值
	 * @return 实体对象
	 */
	public T get(String propertyName, Object value);
	
	/**
	 * 根据属性名和属性值获取实体对象集合.
	 * 
	 * @param propertyName
	 *            属性名称
	 * @param value
	 *            属性值
	 * @return 实体对象集合
	 */
	public List<T> getList(String propertyName, Object value);
	
	/**
	 * 根据属性名和属性值模糊查询实体对象集合.
	 * 
	 * @param propertyName
	 *            属性名称
	 * @param value
	 *            属性值
	 * @param module
	 *            模糊查询的类型
	 *            1:左右匹配(默认，即module为null)
	 *            2:左匹配
	 *            3:右匹配
	 * @return 实体对象集合
	 */
	public List<T> getListLike(String propertyName, String value, Integer module);
	
	/**
	 * 根据实体ID列表加载实体
	 * @param ids
	 *         实体ID列表
	 * @return 实体对象集合
	 */
	public List<T> getListByIds(Long[] ids);
	
	/**
	 * 获取所有实体对象集合.
	 * 
	 * @return 实体对象集合
	 */
	public List<T> getAll();
	
	/**
	 * 获取所有实体对象总数.
	 * 
	 * @return 实体对象总数
	 */
	public Long getTotalCount();

	/**
	 * 根据属性名、修改前后属性值判断在数据库中是否唯一(若新修改的值与原来值相等则直接返回true).
	 * 
	 * @param propertyName
	 *            属性名称
	 * @param oldValue
	 *            修改前的属性值
	 * @param newValue
	 *            修改后的属性值
	 * @return boolean
	 */
	public boolean isUnique(String propertyName, Object oldValue, Object newValue);
	
	/**
	 * 根据属性名及id，判断属性值是否重复（除id对应的记录外是否还有相同属性值的记录）
	 * @param propertyName 属性值
	 * @param id 
	 * @param newValue
	 * @return
	 */
	public boolean isUniqueById(String propertyName, Long id, Object newValue);
	
	/**
	 * 根据属性名判断数据是否已存在.
	 * 
	 * @param propertyName
	 *            属性名称
	 * @param value
	 *            值
	 * @return boolean
	 */
	public boolean isExist(String propertyName, Object value);

	/**
	 * 保存实体对象.
	 * 
	 * @param entity
	 *            对象
	 * @return ID
	 */
	public void persist(T entity);

	/**
	 * 删除实体对象.
	 * 
	 * @param entity
	 *            对象
	 * @return
	 */
	public void remove(T entity);
	
	/**
	 * 根据ID删除实体对象.
	 * 
	 * @param id
	 *            记录ID
	 */
	public void remove(PK id);

	/**
	 * 根据ID数组删除实体对象.
	 * 
	 * @param ids
	 *            ID数组
	 */
	public void remove(PK[] ids);
	
	public void refresh(T entity);
	
	public Pager findPage(Pager pager, List<SearchFilter> filterList, List<Order> orderList);
	
	public Pager findPage(Pager pager, List<SearchFilter> filterList);
	
	public Pager findPage(Pager pager);
	
	public List<T> findList(Integer first, Integer count, List<SearchFilter> filters, List<Order> orders);
	
	public List<T> findList(CriteriaQuery<T> criteriaQuery, Integer first, Integer count, 
			List<SearchFilter> filterList, List<Order> orderList);
	
	/**
	 * 通过Finder获得分页数据
	 * 
	 * @param finder
	 *            Finder对象
	 * @param pageNo
	 *            页码
	 * @param pageSize
	 *            每页条数
	 * @return
	 */
	public  Pager findByPager(Pager pager, Finder finder);
	
	public Pager findByPager(CriteriaQuery<T> criteriaQuery, Pager pager);
	
	public T update(T entity);
	
	public T updateByUpdater(T entity);
	

	public T updateByUpdateMode(T entity, UpdateMode mode);
	
	public T update(T entity, String ignoreProperties[]);
	
	/**
	 * 通过Updater更新对象
	 * 
	 * @param entity
	 * @param mode
	 * @return
	 */
	public T updateByUpdater(Updater<T> updater);
	
	/**
	 * 页面可用手机 邮箱 用户名 卡号  来进行查询
	 * @param filters 页面来的过滤条件
	 * @return 执行后的过滤条件
	 */
	public Map<String, Object> integrationParameter(Map<String, Object> filterParams);

	public  Pager findByPagerForHessian(Pager pager, Finder finder);
}
